﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Configuration;
using System.Reflection;
using LibInterface;

namespace Server.ProjectHelpers
{
    public class ProjectDecorator
    {
        private int _id;
        private Config _config;
        private string _projectPath;

        private LibInterface.IServerLib _application;

        public event EventHandler OnChange;

        private void _change()
        {
            if(this.OnChange != null)
            this.OnChange(this, EventArgs.Empty);
        }

        public LibInterface.IServerLib Lib
        {
            get
            {
                return _application;
            }
        }

        public int Id
        {
            get
            {
                return _id;
            }
        }

        public Config Configuration
        {
            get
            {
                return _config;
            }
        }

        public string Name
        {
            get
            {
                return _config.Name;
            }
        }

        public List<string> ClientLibFiles
        {
            get
            {
                return _config.ClientLibFiles;
            }

        }

        public int MaxDaysOfCompiuting
        {
            get
            {
                return _config.MaxDaysOfCompiuting;
            }
        }

        public float Progress
        {
            get
            {
                if (this._application.CanGetProgrss)
                {
                    return this._application.Progress / 255;
                }
                else if (this._application.IsDone)
                {
                    return 1;
                }
                else
                {
                    return 0;
                }

            }
        }

        public LibInterface.Compiuting GetDataToCompiuting()
        {
            this._change();
            if (_application.HasDataWaiting)
            {
                return _application.GetDataToCompiuting();
            } else {
                throw new NoDataComputingExeption(this._id);
            }
        }

        public ProjectDecorator(int id, string name)
        {
            this._projectPath = Path.Combine(Environment.CurrentDirectory, ConfigurationSettings.AppSettings["ProjectPath"], name);
            XmlSerializer configReader = new XmlSerializer(typeof(Config));
            using (Stream file = File.OpenRead(Path.Combine(this._projectPath, "project.xml")))
            {
                _config = (Config)configReader.Deserialize(file);
            }
            
            _id = id;

            Assembly a = Assembly.LoadFrom(Path.Combine(this._projectPath, this._config.ServerLibFile));
            Type t = a.GetType("PrimesServerLib.Controller");
            _application = (LibInterface.IServerLib)Activator.CreateInstance(t);
            using (FileStream fs = File.OpenRead(Path.Combine(this._projectPath, "config.xml")))
            {
                this._application.Initialize(fs, this._projectPath);
            }
        }

    }
}
